package com.bootdo.clouddo3d.controller;

import java.io.*;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;

import com.bootdo.clouddo3d.clients.ChainClient;
import com.bootdo.clouddo3d.clients.GetUser;
import com.bootdo.clouddo3d.domain.FileDO;
import com.bootdo.clouddo3d.service.FileService;
import com.bootdo.clouddocommon.annotation.Log;
import com.bootdo.clouddocommon.context.FilterContextHandler;
import com.bootdo.clouddocommon.service.ChainRpcService;
import com.bootdo.clouddocommon.utils.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;

import com.bootdo.clouddocommon.utils.PageUtils;
import com.bootdo.clouddocommon.utils.Query;
import com.bootdo.clouddocommon.utils.R;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

/**
 * 文件上传
 *
 * @author chglee
 * @email 1992lcg@163.com
 * @date 2018-03-12 12:17:36
 */
@RefreshScope
@RestController
@RequestMapping("/file")
public class FileController {
    @Value("${app.filePath}")
    String filePath;

    @Value("${app.pre}")
    String filePre;

    @Value("${switch.chain}")
    boolean switchChain;

    @Value("${url.uploadUrl}")
    String uploadUrl; // 网页上传的位置

    @Autowired
    private FileService fileService;

    @Autowired
    ChainClient chainClient;
    @Autowired
    GetUser getUser;

    @GetMapping("{id}")
    public R get(@PathVariable Long id) {
        return R.data(fileService.get(id));
    }


    // 参考http://www.javashuo.com/article/p-khbbhysp-de.html
    @Log("下载三维重建文件")
    @GetMapping("/download")
    public void fileDownLoad(@RequestParam("id") Long id,HttpServletResponse response) throws UnsupportedEncodingException, FileNotFoundException {
        //改一改
        FileDO fileDO = fileService.get(id);
        String fileName = fileDO.getFileName();
        String url = fileDO.getUrl();

        response.setContentType("multipart/form-data");
        response.setCharacterEncoding("UTF-8");

        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName,"UTF-8"));


        try {
            // 以流的形式下载文件。
            InputStream fis = new BufferedInputStream(new FileInputStream(url));
            BufferedInputStream bufferedInputStream = new BufferedInputStream(fis);

            ServletOutputStream outputStream = response.getOutputStream();

            byte[] buffer = new byte[1024];
            int length =bufferedInputStream.read(buffer);
            while (length != -1) {

                outputStream.write(buffer,0, length);

                length=bufferedInputStream.read(buffer);

            }

            outputStream.flush();
            bufferedInputStream.close();
            outputStream.close();
//            上传操作上链
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            String uploader = authentication.getName();
            SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            fmt.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
            String str = chainClient.upChain("nothing ",
                    fileDO.getFileName()+"",
                    fileDO.getFileName()+"",
                    Long.toString(fileDO.getSize()/1024)+"KB",
                    fmt.format(new Date())+"",
                    uploader+"",
                    "下载");
            System.out.println("下载操作上链成功");
        } catch (IOException e) {
            System.out.println("下载失败");
//            return R.error("下载失败");
        }
//        return R.ok("下载成功");
    }


    @GetMapping("getToken")
    public R getToken() {
        return R.ok().put("token", FilterContextHandler.getToken()).put("url", uploadUrl)
                .put("key", UUID.randomUUID().toString());
    }

    @Autowired
    ChainRpcService chainService;

    @Log("上传三维重建文件")
    @PostMapping("upload")
    public R upload(MultipartFile file, String key) {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            String uploader = authentication.getName();

            byte[] photoData = file.getBytes();
            String resPath = FileUtils.saveFile(photoData, filePath, key, file.getOriginalFilename());
            FileDO newFile = new FileDO() {{
                setCreateDate(new Date());
                setUrl(resPath);
                setUploader(uploader);
                setFileName(file.getOriginalFilename());
                setType(getNameType(file.getOriginalFilename()));
                setSize(file.getSize());
            }};

            /*远程调用*/
            if (switchChain) {
                SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String str = chainClient.upChain("nothing ",
                        newFile.getFileName() + "",
                        newFile.getFileName() + "",
                        Long.toString(newFile.getSize() / 1024) + "KB",
                        fmt.format(newFile.getCreateDate()) + "",
                        uploader + "",
                        "上链");
                System.out.println(str);
            }
            fileService.save(newFile);

            System.out.println("上传成功");
            return R.ok().put("resPath", resPath);
        } catch (IOException e) {
            e.printStackTrace();
            return R.error("文件上传失败");
        }
    }

    /**
     * 文件类型
     * **/
    public String getNameType(String originName) {
        if (originName != null) {
            return originName.split("\\.")[1];
        }else {
            return "其他";
        }
    }

    /**
    * 根据文件名查找文件
    * **/
    @Log("搜索三维重建文件")
    @GetMapping("getList/{fileName}")
    public R get(@PathVariable String fileName) {
        Map<String, Object> params = new HashMap<>();
        List<FileDO> fileList = new ArrayList<>(fileService.getList("%" + fileName + "%"));
        params.put("limit",fileList.size());
        params.put("page", fileList.size()/10 + 1);
        Query query = new Query(params);
        System.out.println(query.toString());
        int total = fileService.count(query);
        PageUtils pageUtils = new PageUtils(fileList, fileList.size());
        return R.page(pageUtils);
    }


    /**
     * 分页查询
     */
    @Log("查看三维重建文件列表")
    @GetMapping
    public R list(@RequestParam Map<String, Object> params) {
        Query query = new Query(params);
        List<FileDO> fileList = fileService.list(query);
        int total = fileService.count(query);
        PageUtils pageUtils = new PageUtils(fileList, total);

        return R.page(pageUtils);
    }

    /**
     * 保存
     */
    @PostMapping
    public R save(FileDO file) {
        return R.operate(fileService.save(file) > 0);
    }

    /**
     * 修改
     */
    @PutMapping
    public R update(FileDO file) {
        return R.operate(fileService.update(file) > 0);
    }

    /**
     * 删除
     */
    @Log("删除三维重建文件")
    @DeleteMapping
    public R remove(Long id) {
        return R.operate(fileService.remove(id) > 0);
    }

    /**
     * 删除
     */
    @DeleteMapping("/batchRemove")
    public R remove(@RequestParam("ids[]") Long[] ids) {
        return R.operate(fileService.batchRemove(ids) > 0);
    }
}
